﻿//
// Created by francklinson on 2021/3/24.
//

#include "StringGood.h"
#include <cstring>              // stringGood.h for some

using std::cin;
using std::cout;

// initializing static class member

int StringGood::num_strings = 0;

// static method
int StringGood::HowMany()
{
    return num_strings;
}

// class methods
StringGood::StringGood(const char *s)   // construct StringGood from C stringGood
{
    len = std::strlen(s);        // set size
    str = new char[len + 1];     // allot storage
    std::strcpy(str, s);         // initialize pointer
    num_strings++;               // set object count
}

StringGood::StringGood()                 // default constructor
{
    len = 4;
    str = new char[1];
    str[0] = '\0'; // default stringGood
    num_strings++;
}

StringGood::StringGood(const StringGood &st)
{
    num_strings++;            // handle static member update
    len = st.len;             // same length
    str = new char[len + 1]; // allot space
    std::strcpy(str, st.str); // copy stringGood to new location
}

StringGood::~StringGood()  // necessary destructor
{
    --num_strings; // required
    delete[] str; // required
}

// overloaded operator methods

// assign a StringGood to a StringGood
StringGood &StringGood::operator=(const StringGood &st)
{
    if (this == &st)
        return *this;
    delete[] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

// assign a C stringGood to a StringGood
StringGood &StringGood::operator=(const char *s)
{
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

// read-write char access for non-const StringGood
char &StringGood::operator[](int i)
{
    return str[i];
}

// read-only char access for const StringGood
const char &StringGood::operator[](int i) const
{
    return str[i];
}

// overloaded operator friends

bool operator<(const StringGood &st1, const StringGood &st2)
{
    return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const StringGood &st1, const StringGood &st2)
{
    return st2 < st1;
}

bool operator==(const StringGood &st1, const StringGood &st2)
{
    return (std::strcmp(st1.str, st2.str) == 0);
}

// simple StringGood output
ostream &operator<<(ostream &os, const StringGood &st)
{
    os << st.str;
    return os;
}

// quick and dirty StringGood input
istream &operator>>(istream &is, StringGood &st)
{
    char temp[StringGood::CINLIM];
    is.get(temp, StringGood::CINLIM);
    if (is)
        st = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}